package xq.gwt.ui.crud;

import java.util.ArrayList;

import xq.gwt.mvc.model.AbstractEntityModel;
import xq.gwt.mvc.model.CommandModel;
import xq.gwt.mvc.model.EntityModel;
import xq.gwt.mvc.model.PersistableEntityModel;
import xq.gwt.mvc.model.PropertyGroup;
import xq.gwt.mvc.model.PropertyModel;
import xq.gwt.mvc.model.PropertyModelList;

public class EntityEditorModel extends AbstractEntityModel {
	
	private static final long serialVersionUID = 2937454751510645244L;
	private PersistableEntityModel entity;	
	private NewEntityCommand newEntityCommand;
	private SaveEntityCommand saveEntityCommand;
	private DeleteEntityCommand deleteEntityCommand;
	private CancelEntityEditCommand cancelCommand;
	private RefreshEntityCommand refreshCommand;
	private boolean insertDenied = false;
	private boolean deleteDenied = false;
	private boolean updateDenied = false;
	private boolean showRefresh = true;
	private PropertyModelList propertyList = new PropertyModelList();	
	private BeforePersistListener beforePersistListener;
	private PropertyGroup[] propertyGroups;
		
	public EntityEditorModel(){
		newEntityCommand = new NewEntityCommand(this);
		saveEntityCommand = new SaveEntityCommand(this);
		cancelCommand = new CancelEntityEditCommand();
		deleteEntityCommand = new DeleteEntityCommand(this);
		refreshCommand = new RefreshEntityCommand(this);
	}
	
	@Override
	public String getTitle() {
		String title = "Editor";
		if(entity != null){
			title = entity.getTitle();
		}		
		return title;
	}

	@Override
	public PropertyModel[] getProperties() {
		if(entity != null){
			return entity.getProperties();
		}
		return null;
	}

	@Override
	public CommandModel[] getCommands() {		
		ArrayList<CommandModel> commandList = new ArrayList<CommandModel>();
		if(!isInsertDenied()){
			commandList.add(newEntityCommand);
		}
		if(entity != null){
			if(!isSaveDenied()){
				commandList.add(saveEntityCommand);
			}
			
			if(!isDeleteDenied()){
				commandList.add(deleteEntityCommand);
			}
			
			if(!isSaveDenied()&&!isInsertDenied()){
				commandList.add(cancelCommand);
			}
			
			if(isShowRefresh()){
				commandList.add(refreshCommand);
			}
			
			CommandModel[] entityCommands = entity.getCommands();
			if(entityCommands != null){
				for (int i = 0; i < entityCommands.length; i++) {
					commandList.add(entityCommands[i]);
				}
			}
		}
		
		
		
		CommandModel[] commands = new CommandModel[commandList.size()];
		commandList.toArray(commands);		
		return commands;
	}
	
	public void setEntity(PersistableEntityModel entity){
		this.entity = entity;		
		saveEntityCommand.setEntity(entity);
		cancelCommand.setEntity(entity);
		deleteEntityCommand.setEntity(entity);
		notifyEnityChanged();
	}
	
	public PersistableEntityModel getEntity(){
		return this.entity;
	}
	
	public NewEntityCommand getNewEntityCommand() {
		return newEntityCommand;
	}


	public SaveEntityCommand getSaveEntityCommand() {
		return saveEntityCommand;
	}
	
	public RefreshEntityCommand getRefreshCommand() {
		return refreshCommand;
	}
	
	

	public boolean isInsertDenied() {
		return insertDenied;
	}

	public void setInsertDenied(boolean insertDenied) {
		this.insertDenied = insertDenied;
	}

	public boolean isDeleteDenied() {
		return deleteDenied;
	}

	public void setDeleteDenied(boolean deleteDenied) {
		this.deleteDenied = deleteDenied;
	}

	public boolean isUpdateDenied() {
		return updateDenied;
	}

	public void setUpdateDenied(boolean updateDenied) {
		this.updateDenied = updateDenied;
	}

	public boolean isSaveDenied(){
		if(entity == null)
			return true;
		if(isInsertDenied() && isUpdateDenied()){
			return true;
		}
		
		return false;		
	}
	
	
	
	public boolean isShowRefresh() {
		return showRefresh;
	}

	public void setShowRefresh(boolean showRefresh) {
		this.showRefresh = showRefresh;
	}

	public boolean isValid(){	
		return propertyList.isValid();
	}

	
	public BeforePersistListener getBeforePersistListener() {
		return beforePersistListener;
	}

	public void setBeforePersistListener(BeforePersistListener beforePersistListener) {
		this.beforePersistListener = beforePersistListener;
	}

	public PropertyGroup[] getPropertyGroups() {
		return propertyGroups;
	}

	public void setPropertyGroups(PropertyGroup[] propertyGroups) {
		this.propertyGroups = propertyGroups;
	}

	@Override
	public EntityModel newInstance() {		
		return new EntityEditorModel();
	}
		
}
